package com.hzgj.bcl.soa.cicada.lb;

import com.google.common.collect.Lists;

import com.hzgj.bcl.soa.cicada.sender.Sender;
import com.hzgj.bcl.soa.config.ReferenceDef;

import java.util.List;
import java.util.Random;

/**
 * A loadbalacing strategy that randomly distributes traffic amongst existing
 * servers.
 */
public class RandomRule extends AbstractRule {

    Random rand;

    public RandomRule() {
        rand = new Random();
    }

    /**
     * Randomly choose from all living servers
     */
    @Override
    public Sender choose(LoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Sender sender = null;

        Rule.RuleObject pair = (Rule.RuleObject) key;
        ReferenceDef referenceDef = new ReferenceDef();
        referenceDef.setService(pair.getService());

        if (Thread.interrupted()) {
            return null;
        }
        List<Sender> upList = Lists.newArrayList(lb.getRouter().getUpSenders(referenceDef));
        List<Sender> downList = Lists.newArrayList(lb.getRouter().getMarkedDownSenders(referenceDef));

        int serverCount = upList.size();
        if (serverCount != 0) {
            int index = rand.nextInt(serverCount);
            sender = upList.get(index);
        }
        if (sender == null && downList.size() > 0) {
            int index = rand.nextInt(downList.size());
            sender = downList.get(index);
        }
        return sender;
    }

    @Override
    public String getName() {
        return "random";
    }
}
